package com.dingwen.frame.controller.base;

import com.baomidou.mybatisplus.extension.service.IService;
import com.dingwen.frame.constant.ValidationGroups;
import com.dingwen.frame.dto.BaseDto;
import com.dingwen.frame.vo.Result;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.validation.groups.Default;
import java.io.Serializable;
import java.util.List;

/**
 * {@code BaseController}是顶级Controller，封装基础单表增删改查。
 * <p>
 * <p>
 * rest示例如下：
 * <ul>
 *  <li>GET / 综合查询(区分返回值是{@code List<T>}还是@{List<Map<String,Object>>}),如果请求参数[pageSize,pageNum]有一个为null则执行查询所有
 *  <li>GET /{id} 根据主键查询单个。
 *  <li>GET /ids 携带请求参数主键查询 示例：ids 1,2,3 ，集合长度至少为2。
 *  <li>GET /count 获取数据表总记录条数
 *  <li>
 *  <li>PUT / 请求体（T） 修改单个实体，对象主键必须存在
 *  <li>PUT /patch {@link BaseDto<T>} 批量修改，每一个对象的主键必须存在否则回滚
 *  <li>
 *  <li>POST / 请求体（T） 新增单个实体
 *  <li>POST /path {@link BaseDto<T>} 批量新增
 *  <li>
 *  <li>DELETE /id 根据主键删除记录
 *  <li>DELETE /ids 携带请求参数主键删除,参数示例：ids 1,2,3 ，集合长度至少为2。
 * <ul/>
 *
 * @author dingwen
 * @date 2021.06.30 09:44
 * @see IService
 * @since 1.0.0-SNAPSHOT
 */
@Validated
public interface IBaseController<T> {


    /**
     * 根据Id查询，返回单个实体
     *
     * @param id 数据表主键
     * @return {@link Result}
     */
    Result find(@NotNull(message = "查询主键不能为空") Serializable id);


    /**
     * 根据List<id>查找实体
     *
     * @param ids id 传参示例： 1,2,3 集合长度至少为2
     * @return {@link Result}
     */
    Result find(@NotNull(message = "参数ids不能为空") @Size(min = 2, message = "主键集合必须大于等于2") List<Serializable> ids);


    /**
     * 无条件查询所有
     *
     * @param flag true： 查询List<T>返回    false: 查询List<Map<String,Object>返回,默认值为true
     * @return {@link Result}
     */
    Result find(boolean flag);

    /**
     * 无条件分页查询
     *
     * @param pageSize 页面大小
     * @param pageNum  页面num
     * @param flag     true： 查询List<T>返回    false: 查询List<Map<String,Object>返回,默认值为true
     * @return {@link Result}
     */
    Result find(Integer pageSize, Integer pageNum, boolean flag);


    /**
     * 获取数据表总记录条数
     *
     * @return {@link Result}
     */
    Result count();


    /**
     * 修改,对象ID,主键必须有值
     *
     * @param t t
     * @return {@link Result}
     */
    Result modify(@Validated({ValidationGroups.Modify.class, Default.class}) T t);


    /**
     * 批量修改,对象主键必须要有值
     *
     * @param baseDto baseDto
     * @return {@link Result}
     */
    Result modify(@Validated({ValidationGroups.Modify.class, Default.class}) BaseDto<T> baseDto);


    /**
     * 保存
     *
     * @param t t
     * @return {@link Result}
     */
    Result save(@Validated({ValidationGroups.Save.class, Default.class}) T t);


    /**
     * 批量保存
     *
     * @param baseDto baseDto
     * @return {@link Result}
     */
    Result save(@Validated({ValidationGroups.Save.class, Default.class}) BaseDto<T> baseDto);


    /**
     * 删除
     *
     * @param id id
     * @return {@link Result}
     */
    Result remove(@NotNull(message = "主键不能为空") Serializable id);

    /**
     * 根据主键集合批量删除
     *
     * @param ids id
     * @return {@link Result}
     */
    Result remove(@NotNull(message = "参数ids不能为空") @Size(min = 2, message = "主键集合必须大于等于2") List<Serializable> ids);

}
